//
//  BaseSocketManager.m
//  Builder
//
//  Created by JCK on 2017/12/5.
//  Copyright © 2017年 JCK. All rights reserved.
//
/*
 /// <summary>
 /// 服务器收到心跳协议号
 /// </summary>
 Heart = 1000,
 /// <summary>
 /// 服务器收到经纬度
 /// </summary>
 AcceptLocation = 1001,
 /// <summary>
 /// 服务器收到用工申请
 AcceptReplayChe = 1002,
 /// <summary>
 /// 服务器“发送”用工申请给工人
 SendReplayChe = 1003,
 /// <summary>
 /// 服务器收到取消订单通知
 /// </summary>
 AcceptCancelOrder = 1004,
 /// <summary>
 /// 服务器收到抢单成功通知
 /// </summary>
 AcceptOrderSuccess = 1005,
 /// <summary>
 /// 服务器“发送”订单状态变更通知
 /// </summary>
 SendOrderStatus = 1006,
 /// <summary>
 /// 服务器接收订单状态通知
 /// </summary>
 AccptOrderStatus = 1007,
 /// <summary>
 /// 服务器发送取消订单给工人
 /// </summary>
 SendCancelOrder = 1008,
 
 /// <summary>
 /// 雇主方付款成功指令
 /// </summary>
 PaySuccess=1013,
 /// <summary>
 /// 雇主方付款成功回传指令，更新工人钱包
 /// </summary>
 PayReturn=1014,
 
 1、“APP” 发送心跳协议号：1000
 2、“APP” 发送经纬度： 1001
 3、“APP” 发送用工申请：1002
 4、服务器  发送用工申请给工人：1003
 5、“APP” 发送取消订单通知：1004
 6、“APP” 发送抢单成功通知：1005
 7、服务器  发送订单状态变更通知：1006
 8、“APP” 发送订单状态通知：1007
 9、服务器  发送取消订单给工人：1008
 10、“APP”发送雇主方付款成功指令：1013
 11、服务器 发送雇主方付款成功回传指令，更新工人钱包：1014
 */
#import "BaseSocketManager.h"
#import "UserInfoModel.h"
#import "MJExtension.h"
#import "SVProgressHUD.h"
#import "BaseWebViewController.h"
//#import "ChooseIdentityViewController.h"
#import "NetManager.h"

static BaseSocketManager *manager = nil;
@interface BaseSocketManager()<GCDAsyncSocketDelegate>
{
    GCDAsyncSocket *socket;
    int socketConentTag;
}
@property (strong, nonatomic) NSTimer *timer;
@end

@implementation BaseSocketManager
// 单例
+ (instancetype)shareInstance
{
    static dispatch_once_t oneToken;
    dispatch_once(&oneToken, ^{
        if (!manager) {
            manager = [[[self class] alloc] init];
        }
    });
    return manager;
}

- (instancetype)initWith:(RequestStates)requet
{
    self = [super init];
    if (self)
    {
        if (!socket)
        {
            if (requet == 0)
            {
//                [self openSocketConnect];
            }
            else
            {
//                [self closeSocketConnect];
            }
            
        }
    }
    return self;
}
+ (void)SocketOpen
{
    [manager openSocketConnect];
}
+ (void)Socketclose
{
     [manager closeSocketConnect];
}
#pragma mark - 开始socket连接
-(void)openSocketConnect
{
    /*
     172.16.1.146
     6600
     */
    socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    //socket.delegate = self;
    NSError *err = nil;
    if(![socket connectToHost:SocketServerAddressIP onPort:kDefaultPort error:&err])
    {
        NSLog(@"socket:%@",err);
    }
    else
    {
        NSLog(@"ok  打开端口");
        [self addTimer];
        
    }
}

#pragma mark -
#pragma mark - 关闭连接
-(void)closeSocketConnect
{
    if(socket)
    {
        [socket disconnect];
        [self closeTimer];
    }
    
}
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag

{
    
    NSLog(@"thread(%),onSocket:%p didWriteDataWithTag:%d",[[NSThread currentThread] name],
          
          sock,tag);
    
    if([socket isConnected])
    {
        NSLog(@"\n\n connnected \n\n");
    }
}


-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    NSLog(@"123");
    NSLog(@"%@",[NSString stringWithFormat:@"连接到:%@",host]);
    //用于验证socket 登录用户
    // {"PNo":1000,"userid":"","ClientType":"","SendTo":"","Content":""}
    NSMutableDictionary *mdict = [[NSMutableDictionary alloc] initWithCapacity:0];
    [mdict setObject:[UserInfoModel shareInstance].UserId forKey:@"UId"];
    [mdict setObject:@"1000" forKey:@"PNo"];
    [mdict setObject:@"" forKey:@"Data"];
    [mdict setObject:@"" forKey:@"To"];
    [mdict setObject:UserPhoneName forKey:@"APP"];
//
    NSString *strJason = [mdict mj_JSONString];
//
    NSLog(@"\n\n Json string :%@ \n\n",strJason);
    [SVProgressHUD showSuccessWithStatus:@"链接成功"];
    if([socket isDisconnected])
    {
        NSLog(@"2");
    }
    else
    {
        NSLog(@"1");
    }
    
    [socket writeData:[strJason dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
    
    [socket readDataWithTimeout:-1 tag:0];
    
    
}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
//    ErrorShow(@"链接中断");
    NSLog(@"\n\n 关闭了socket连接 \nsock.userData %@ \n",sock);
    [self closeTimer];
//    if ([NetManager shareInstance].isExit == NO)
//    {
//        [[NSNotificationCenter defaultCenter] postNotificationName:@"socketConent" object:nil];
//    }
    
}
#pragma mark - 发送消息
- (void)sendDataToSocket:(NSString *)data PNo:(NSString *)pno successBlock:(SuccessBlock)successBlock
{
    NSMutableDictionary *mdict = [[NSMutableDictionary alloc] initWithCapacity:0];
    
    [mdict setObject:[UserInfoModel shareInstance].UserId forKey:@"UId"];
    [mdict setObject:pno forKey:@"PNo"];
    [mdict setObject:data forKey:@"Data"];
    [mdict setObject:@"" forKey:@"To"];
    [mdict setObject:UserPhoneName forKey:@"APP"];
    NSString *strJason = [mdict mj_JSONString];
    
    NSLog(@"sendDataToSocket \n\n Json string :%@ \n\n",strJason);
    
    if([socket isDisconnected]) return;
    
    [socket writeData:[strJason dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
    
    [socket readDataWithTimeout:-1 tag:0];
    successBlock(@"发送成功");
    
}
#pragma mark -
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSString *newMessage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    NSLog(@" 读取数据:%@",newMessage);
    
    if (newMessage)
    {
        NSData *JSONData = [newMessage dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *mdict = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"%@",mdict);
        
        NSNumber *flag = [mdict valueForKey:@"Code"];
        int success = [flag intValue];
        NSString *PNo = [NSString stringWithFormat:@"%@",[mdict valueForKey:@"PNo"]];
        NSLog(@"%@",PNo);
        
        //修改以后需要显示给的数据字段
        NSString *msg = [mdict valueForKey:@"Msg"];
        NSString *clickUrl = [mdict valueForKey:@"ClickUrl"];
        NSString *msgType = [mdict valueForKey:@"MsgType"];
        
        NSLog(@"msg =  =%@",msg);
        
        if (![PNo isEqualToString:@"1000"])
        {
            //代理传值
//            if ([PNo isEqualToString:@"1003"])
//            {
//                [_oderPNodelegate NewOderPNo:PNo];
//            }
//            else
            if ([PNo isEqualToString:@"1099"])
            {
                [SVProgressHUD showSuccessWithStatus:@"测试连接成功"];
            }
            else
            {
               /*
                1、“APP” 发送心跳协议号：1000
                2、“APP” 发送经纬度： 1001
                3、“APP” 发送用工申请：1002
                4、服务器  发送用工申请给工人：1003
                5、“APP” 发送取消订单通知：1004
                6、“APP” 发送抢单成功通知：1005
                7、服务器  发送订单状态变更通知：1006
                8、“APP” 发送订单状态通知：1007
                9、服务器  发送取消订单给工人：1008
                10、“APP”发送雇主方付款成功指令：1013
                11、服务器 发送雇主方付款成功回传指令，更新工人钱包：1014
                */
                switch ([PNo integerValue])
                {
                    case 1003:
                    {
                        
//                        UIAlertView *alView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您有一张新的订单可抢" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
//                        [alView show];
                        [self showOrderContent:msg withMsgType:msgType withUrl:clickUrl withInteger:1003];
                        
                    }
                        break;
                    case 1006:
                    {
//                        UIAlertView *alView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您有新的订单消息" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
//                        [alView show];
                        
                        [self showOrderContent:msg withMsgType:msgType withUrl:clickUrl withInteger:1006];
                    }
                        break;
                    case 1008:
                    {
//                        UIAlertView *alView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的订单已被取消" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
//                        [alView show];
                        [self showOrderContent:msg withMsgType:msgType withUrl:clickUrl withInteger:1008];
                        
                    }
                        break;
                    case 1014:
                    {
//                        UIAlertView *alView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的工程款已到账,请核实查收" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
//                        [alView show];
                        [self showOrderContent:msg withMsgType:msgType withUrl:clickUrl withInteger:1014];
                        
                    }
                        break;

                        
                    default:
                        break;
                }
                
//                 [_delegate passValue:PNo];
                [[NSNotificationCenter defaultCenter] postNotificationName:@"newOderSend" object:nil];
            }

        }
        
        if(success == 1)
        {
            NSLog(@"链接socket成功");
        }
        else
        {
            NSLog(@"链接socket失败");
        }
        
        NSString *token = [mdict valueForKey:@"Token"];
        
        if (token != nil  && ![token isEqual:[NSNull null]]) {
            if (![token isEqualToString:[UserInfoModel shareInstance].usetCode]) {
                
                [self againLogin];
            }
        }
        
        
        
    }
    [socket readDataWithTimeout:-1 tag:0];
    
}

//重新登录
- (void) againLogin {
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"您的账号在其他地方登录" preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
        [self closeSocketConnect];
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        [userDefaults removeObjectForKey:@"passWord"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"closeTmer" object:nil];
        [NetManager shareInstance].isExit = YES;
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"socketConent" object:nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadApp" object:nil];
    }];
    
    [alert addAction:okAction];
    
    [[self getCurrentVC] presentViewController:alert animated:YES completion:nil];
    
    
}


#pragma mark - 断线重连
- (void)socketConent
{
    NSLog(@"断线重连");
    if([socket isDisconnected])
    {
        NSLog(@"启动");
        [self openSocketConnect]; // 打开socket
    }
    else
    {
        NSLog(@"不启动");
    }
    
}
#pragma mark - 定时器
- (void)addTimer
{
    // 过滤计时器
    if ([_timer isValid])
    {
        [_timer invalidate];
        _timer = nil;
    }
    _timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(hearTimerAction) userInfo:nil repeats:YES];
    
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop addTimer:self.timer forMode:NSRunLoopCommonModes];
    NSLog(@" 定时器启动 ");
}
- (void)closeTimer
{
    //取消定时器
    [_timer invalidate];
    _timer = nil;
    //关闭定时器
    [_timer setFireDate:[NSDate distantFuture]];
}
- (void)hearTimerAction
{
//    socketConentTag --;
//    if (socketConentTag == -20)
//    {
//        [self socketConent];
//    }
    //用于验证socket 登录用户
    // {"PNo":1000,"userid":"","ClientType":"","SendTo":"","Content":""}
    NSMutableDictionary *mdict = [[NSMutableDictionary alloc] initWithCapacity:0];
    [mdict setObject:[UserInfoModel shareInstance].UserId forKey:@"UId"];
    [mdict setObject:@"1000" forKey:@"PNo"];
    [mdict setObject:@"" forKey:@"Data"];
    [mdict setObject:@"" forKey:@"To"];
    [mdict setObject:UserPhoneName forKey:@"APP"];
    NSString *strJason = [mdict mj_JSONString];
    
    NSLog(@"定时器启动\n\n Json string :%@ \n\n",strJason);
    
    if([socket isDisconnected])
    {
        NSLog(@"Disconnected");
    }
    else
    {
        NSLog(@"connected");
    }
    //        return;
    
    [socket writeData:[strJason dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
    
    [socket readDataWithTimeout:-1 tag:0];
}

//显示订单的内容
- (void) showOrderContent: (NSString *) message
              withMsgType: (NSString *) msgType
                  withUrl: (NSString *) clickUrl
              withInteger: (NSInteger) intege {
    
    message = [self htmlEntityDecode:message];
    //2.将HTML字符串转换为attributeString
    NSAttributedString * attributeStr = [self attributedStringWithHTMLString:message];
    
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:msgType message:message preferredStyle:UIAlertControllerStyleAlert];
    [alertController setValue:attributeStr forKey:@"attributedMessage"];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"忽略" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        [self refreshNotifi:intege];
    }];
    
    [cancelAction setValue:[UIColor colorWithRed:155/255.0 green:155/255.0 blue:155/255.0 alpha:1] forKey:@"_titleTextColor"];
    
    UIAlertAction *seeAction = [UIAlertAction actionWithTitle:@"马上去看" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
        //去查看订单的详情
        BaseWebViewController *sub = [[BaseWebViewController alloc] init];
        if ([clickUrl rangeOfString:@"?"].location == NSNotFound) {
            //不存在？
            sub.urlStr = [NSString stringWithFormat:@"%@?_code=%@",clickUrl,[UserInfoModel shareInstance].Token];
            
        } else {
            sub.urlStr = [NSString stringWithFormat:@"%@&_code=%@",clickUrl,[UserInfoModel shareInstance].Token];
        }
        
        sub.title = @"订单详情";
        NSLog(@"%@",sub.title);
        [[self getCurrentVC].navigationController pushViewController:sub animated:YES];
     
    }];
    [seeAction setValue:[UIColor colorWithRed:241/255.0 green:80/255.0 blue:82/255.0 alpha:1] forKey:@"_titleTextColor"];
    
    
    [alertController addAction:cancelAction];
    [alertController addAction:seeAction];
    [[self getCurrentVC] presentViewController:alertController animated:YES completion:^{
        [self refreshNotifi:intege];
    }];
    
}

//发送刷新的通知
- (void) refreshNotifi: (NSInteger) intege {
    
    switch (intege) {
        case 1003:
        {
            [[NSNotificationCenter defaultCenter] postNotificationName:Socket1003 object:nil];
            
        }
            break;
        case 1006:
        {
            [[NSNotificationCenter defaultCenter] postNotificationName:Socket1006 object:nil];
            
        }
            break;
        case 1008:
        {
            
            [[NSNotificationCenter defaultCenter] postNotificationName:Socket1008 object:nil];
        }
            break;
        case 1014:
        {
            [[NSNotificationCenter defaultCenter] postNotificationName:Socket1014 object:nil];
            
        }
            break;
            
        default:
            break;
    }
    
}

//获取当前屏幕显示的viewcontroller
- (UIViewController *)getCurrentVC
{
    UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
    
    UIViewController *currentVC = [self getCurrentVCFrom:rootViewController];
    
    return currentVC;
}

- (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC
{
    UIViewController *currentVC;
    
    if ([rootVC presentedViewController]) {
        // 视图是被presented出来的
        
        rootVC = [rootVC presentedViewController];
    }
    
    if ([rootVC isKindOfClass:[UITabBarController class]]) {
        // 根视图为UITabBarController
        
        currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
        
    } else if ([rootVC isKindOfClass:[UINavigationController class]]){
        // 根视图为UINavigationController
        
        currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
        
    } else {
        // 根视图为非导航类
        
        currentVC = rootVC;
    }
    
    return currentVC;
}

//将 &lt 等类似的字符转化为HTML中的“<”等
- (NSString *)htmlEntityDecode:(NSString *)string
{
    string = [string stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\""];
    string = [string stringByReplacingOccurrencesOfString:@"&apos;" withString:@"'"];
    string = [string stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"];
    string = [string stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"];
    string = [string stringByReplacingOccurrencesOfString:@"&amp;" withString:@"&"]; // Do this last so that, e.g. @"&amp;lt;" goes to @"&lt;" not @"<"
    
    return string;
}

//将HTML字符串转化为NSAttributedString富文本字符串
- (NSAttributedString *)attributedStringWithHTMLString:(NSString *)htmlString
{
    NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
                               NSCharacterEncodingDocumentAttribute :@(NSUTF8StringEncoding) };
    
    NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding];
    
    return [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];
}


@end
